#!/usr/bin/env node

const fs = require('fs');
const path = require('path');

// Get command line arguments
const args = process.argv.slice(2);

if (args.length < 2) {
  console.log('Usage: node add-demo.js <demo-name> <demo-title> [demo-description] [demo-category]');
  console.log('Example: node add-demo.js MyNewDemo "My New Demo" "This is a description of my new demo" "Intermediate"');
  process.exit(1);
}

const demoName = args[0]; // e.g., MyNewDemo
const demoTitle = args[1]; // e.g., "My New Demo"
const demoDescription = args[2] || `Demo for ${demoTitle}`; // e.g., "This is a description of my new demo"
const demoCategory = args[3] || 'Basic'; // e.g., "Basic", "Intermediate", "Advanced"

// Validate demo name (should be in PascalCase)
if (!/^[A-Z][a-zA-Z0-9]*$/.test(demoName)) {
  console.error('Demo name should be in PascalCase (e.g., MyNewDemo)');
  process.exit(1);
}

// Validate category
const validCategories = ['Basic', 'Intermediate', 'Advanced'];
if (!validCategories.includes(demoCategory)) {
  console.log(`Warning: "${demoCategory}" is not a standard category. Using custom category.`);
}

// File paths
const projectRoot = path.join(__dirname, '..');
const demosDir = path.join(projectRoot, 'src', 'demos');
const demoFile = path.join(demosDir, `${demoName}.vue`);
const registryFile = path.join(projectRoot, 'src', 'demoRegistry.js');
const loaderFile = path.join(projectRoot, 'src', 'demoLoader.js');
const utilsFile = path.join(projectRoot, 'src', 'utils', 'demoUtils.js');
const registryTemplateFile = path.join(projectRoot, 'src', 'demoRegistry.template.js');
const loaderTemplateFile = path.join(projectRoot, 'src', 'demoLoader.template.js');
const utilsTemplateFile = path.join(projectRoot, 'src', 'utils', 'demoUtils.template.js');
const demoTemplateFile = path.join(projectRoot, 'src', 'demos', 'DemoTemplate.vue');

// Check if demo already exists
if (fs.existsSync(demoFile)) {
  console.error(`Demo file ${demoName}.vue already exists!`);
  process.exit(1);
}

// Create main files from templates if they don't exist
if (!fs.existsSync(registryFile) && fs.existsSync(registryTemplateFile)) {
  fs.copyFileSync(registryTemplateFile, registryFile);
  console.log('Created demoRegistry.js from template');
}

if (!fs.existsSync(loaderFile) && fs.existsSync(loaderTemplateFile)) {
  fs.copyFileSync(loaderTemplateFile, loaderFile);
  console.log('Created demoLoader.js from template');
}

if (!fs.existsSync(utilsFile) && fs.existsSync(utilsTemplateFile)) {
  fs.copyFileSync(utilsTemplateFile, utilsFile);
  console.log('Created demoUtils.js from template');
}

// Create demo component from template
let demoTemplate;
if (fs.existsSync(demoTemplateFile)) {
  demoTemplate = fs.readFileSync(demoTemplateFile, 'utf8');
  // Replace template placeholders
  demoTemplate = demoTemplate.replace(/Demo Template Component/g, `${demoTitle} Component`);
  demoTemplate = demoTemplate.replace(/DemoTemplate/g, demoName);
  demoTemplate = demoTemplate.replace(/A template for creating new CesiumJS demos/g, demoDescription);
  demoTemplate = demoTemplate.replace(/Category: Basic/g, `Category: ${demoCategory}`);
  
  // Ensure Component Documentation section exists
  if (!demoTemplate.includes('Component Documentation:')) {
    // Add Component Documentation section if it doesn't exist
    const insertPos = demoTemplate.indexOf('-->') + 3;
    const docSection = `\n\n  Component Documentation:\n  ========================\n\n  Title: ${demoTitle}\n  Description: ${demoDescription}\n  Features:\n    - TODO: List key features of this demo\n  Author: CesiumJS Demo Project\n  Date: ${new Date().toLocaleDateString()}`;
    
    demoTemplate = demoTemplate.slice(0, insertPos) + docSection + demoTemplate.slice(insertPos);
  } else {
    // Update existing Component Documentation section
    demoTemplate = demoTemplate.replace(/Title: Demo Template/, `Title: ${demoTitle}`);
    demoTemplate = demoTemplate.replace(/Description: A template for creating new CesiumJS demos/, `Description: ${demoDescription}`);
  }
} else {
  demoTemplate = `<!--
  ${demoTitle} Component

  ${demoDescription}
  
  Category: ${demoCategory}

  Component Documentation:
  ========================

  Title: ${demoTitle}
  Description: ${demoDescription}
  Features:
    - TODO: List key features of this demo
  Author: CesiumJS Demo Project
  Date: ${new Date().toLocaleDateString()}
-->

<template>
  <BaseCesiumViewer 
    ref="cesiumViewer" 
    :options="viewerOptions" 
    @viewer-ready="onViewerReady"
  />
</template>

<script>
import { ref } from 'vue';
import BaseCesiumViewer from '../core/BaseCesiumViewer.vue';

export default {
  name: '${demoName}',
  components: {
    BaseCesiumViewer
  },
  setup() {
    const cesiumViewer = ref(null);
    const viewerOptions = {
      animation: false,
      timeline: false,
      vrButton: true,
      geocoder: false,
      homeButton: true,
      navigationHelpButton: false,
      scene3DOnly: false,
    };

    // This function is called when the Cesium viewer is ready
    const onViewerReady = (payload) => {
      // eslint-disable-next-line no-unused-vars
      const { viewer, Cesium } = payload;
      
      // TODO: Implement your demo here
      console.log('${demoName} is ready!');
    };

    return {
      cesiumViewer,
      viewerOptions,
      onViewerReady
    };
  }
};
</script>

<style scoped>
/* 
  Add any custom styles for your demo here
*/
</style>
`;
}

// Write demo file
fs.writeFileSync(demoFile, demoTemplate);
console.log(`Created demo component: ${demoFile}`);

// Update demo registry
const registryContent = fs.readFileSync(registryFile, 'utf8');
const demosArrayRegex = /const demos = \[\s*([\s\S]*?)\s*\];/;
const match = registryContent.match(demosArrayRegex);

if (!match) {
  console.error('Could not find demos array in demoRegistry.js');
  process.exit(1);
}

const demosArrayContent = match[1];
const lastDemoRegex = /{\s*id:.*?}[,\s]*$/s;
const lastDemoMatch = demosArrayContent.match(lastDemoRegex);

if (!lastDemoMatch) {
  console.error('Could not find last demo in demos array');
  process.exit(1);
}

// Create new demo entry
const kebabCaseName = demoName.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
const newDemoEntry = `  {
    id: '${kebabCaseName}',
    name: '${demoTitle}',
    description: '${demoDescription}',
    component: () => import('./demos/${demoName}.vue'),
    category: '${demoCategory}'
  }`;

// Insert new demo before the closing bracket of the demos array
const updatedDemosArray = demosArrayContent.replace(lastDemoRegex, `${lastDemoMatch[0]},\n${newDemoEntry}`);
const updatedRegistryContent = registryContent.replace(demosArrayRegex, `const demos = [\n${updatedDemosArray}\n];`);

fs.writeFileSync(registryFile, updatedRegistryContent);
console.log(`Updated demo registry: ${registryFile}`);

// Update demo loader
const loaderContent = fs.readFileSync(loaderFile, 'utf8');
const demosObjectRegex = /const demos = {\s*([\s\S]*?)\s*};/;
const loaderMatch = loaderContent.match(demosObjectRegex);

if (!loaderMatch) {
  console.error('Could not find demos object in demoLoader.js');
  process.exit(1);
}

const demosObjectContent = loaderMatch[1];
const lastDemoLoaderRegex = /.*?:.*?\)[,\s]*$/s;
const lastDemoLoaderMatch = demosObjectContent.match(lastDemoLoaderRegex);

if (!lastDemoLoaderMatch) {
  console.error('Could not find last demo in demos object');
  process.exit(1);
}

// Create new loader entry - properly quote property names with special characters
const propertyName = kebabCaseName.includes('-') ? `'${kebabCaseName}'` : kebabCaseName;
const newLoaderEntry = `  ${propertyName}: () => import('./demos/${demoName}.vue')`;

// Insert new loader entry
const updatedDemosObject = demosObjectContent.replace(lastDemoLoaderRegex, `${lastDemoLoaderMatch[0]},\n${newLoaderEntry}`);
const updatedLoaderContent = loaderContent.replace(demosObjectRegex, `const demos = {\n${updatedDemosObject}\n};`);

fs.writeFileSync(loaderFile, updatedLoaderContent);
console.log(`Updated demo loader: ${loaderFile}`);

// Update demo utils
const utilsContent = fs.readFileSync(utilsFile, 'utf8');
const demoFilePathsRegex = /const demoFilePaths = {\s*([\s\S]*?)\s*};/;
const utilsMatch = utilsContent.match(demoFilePathsRegex);

if (!utilsMatch) {
  console.error('Could not find demoFilePaths object in demoUtils.js');
  process.exit(1);
}

const demoFilePathsContent = utilsMatch[1];
const lastDemoPathRegex = /.*?:.*?,?[,\s]*$/s;
const lastDemoPathMatch = demoFilePathsContent.match(lastDemoPathRegex);

if (!lastDemoPathMatch) {
  console.error('Could not find last demo path in demoFilePaths object');
  process.exit(1);
}

// Create new demo path entry - properly quote property names with special characters
const newPathEntry = `    ${propertyName}: '/src/demos/${demoName}.vue'`;

// Insert new path entry
const updatedDemoFilePaths = demoFilePathsContent.replace(lastDemoPathRegex, `${lastDemoPathMatch[0]},\n${newPathEntry}`);
const updatedUtilsContent = utilsContent.replace(demoFilePathsRegex, `const demoFilePaths = {\n${updatedDemoFilePaths}\n  };`);

fs.writeFileSync(utilsFile, updatedUtilsContent);
console.log(`Updated demo utils: ${utilsFile}`);

console.log('\nDemo added successfully!');
console.log('Remember to:');
console.log('1. Implement your demo logic in the onViewerReady function');
console.log(`2. Category is set to: ${demoCategory}`);
if (!validCategories.includes(demoCategory)) {
  console.log('   Note: You are using a custom category which is supported.');
}
console.log('3. Run the application to test your new demo');